package ir.mirrajabi.searchdialog;

import ir.mirrajabi.searchdialog.core.BaseFilter;
import ir.mirrajabi.searchdialog.core.FilterResultListener;
import ir.mirrajabi.searchdialog.core.Searchable;
import ohos.utils.Pair;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

/**
 * Created by MADNESS on 5/14/2017.
 * 设置简单的过滤封装
 */
public class SimpleSearchFilter<T extends Searchable> extends BaseFilter {
    private final float mAccuracyPercentage;
    private ArrayList<T> mItems;
    private FilterResultListener mFilterResultListener;
    private boolean mCheckLCS;
    private Comparator<Pair<T, Integer>> mComparator =
            new Comparator<Pair<T, Integer>>() {
                @Override
                public int compare(Pair<T, Integer> o1, Pair<T, Integer> o2) {
                    if (o1 == null || o2 == null) {
                        return 0;
                    }
                    if (o1.s == null || o2.s == null) {
                        return 0;
                    }
                    return o2.s - o1.s;
                }
            };

    public SimpleSearchFilter(
            List<T> objects, FilterResultListener filterResultListener, boolean checkLCS, float accuracyPercentage) {
        mFilterResultListener = filterResultListener;
        mCheckLCS = checkLCS;
        mAccuracyPercentage = accuracyPercentage;
        mItems = new ArrayList<>();
        synchronized (this) {
            mItems.addAll(objects);
        }
    }

    public SimpleSearchFilter(List<T> objects, FilterResultListener filterResultListener) {
        this(objects, filterResultListener, false, 0);
    }

    @Override
    protected FilterResults executeFiltering(CharSequence charSequence) {
        // 过滤前要处理的方法
        doBeforeFiltering();
        String filterSeq = charSequence.toString().toLowerCase(Locale.ROOT);
        FilterResults result = new FilterResults();
        if (filterSeq.length() <= 0) {
            result.results = mItems;
            result.size = mItems.size();
            return result;
        }

        ArrayList<Pair<T, Integer>> filteredItems = new ArrayList<>();
        for (T item : mItems) {
            if (item.getTitle().toLowerCase(Locale.ROOT).contains(filterSeq)) {
                filteredItems.add(new Pair<>(item, filterSeq.length()));
            } else if (mCheckLCS) {
                int lcsLength = StringsHelper.lcs(item.getTitle(), filterSeq).length();
                if (lcsLength > item.getTitle().length() * mAccuracyPercentage) {
                    filteredItems.add(new Pair<>(item, lcsLength));
                }
            }
        }

        Collections.sort(filteredItems, mComparator);

        ArrayList<T> finalResult = new ArrayList<>();
        for (Pair<T, Integer> item : filteredItems) {
            finalResult.add(item.f);
        }

        result.results = finalResult;
        result.size = finalResult.size();
        return result;
    }

    @Override
    protected void publishFilterResults(CharSequence charSequence, FilterResults results) {
        ArrayList<T> filtered = (ArrayList<T>) results.results;
        mFilterResultListener.onFilter(filtered);
        // 过滤完成后要处理的操作
        doAfterFiltering();
    }
}
